#!/usr/bin/env python
#-*- coding: utf-8 -*-

import re
import random
import json

from diskmap import DiskMap, name2map, map2name

def cluster_init(lst):
    '''lst 格式如下:
        {
            'd2.r2.h3/0': 'admin',
            'd2.r2.h3/1': 'normal',
            'd2.r2.h3/2': 'normal',
            'd1.r1.h2/0': 'stopped',
            'd1.r1.h2/1': 'meta',
            'd1.r1.h2/2': 'deleting',
        }
    '''
    cluster = DiskMap()

    for (k, v) in lst.items():
        if (v == 'stopped' or 'deleting' in v):
            continue

        cluster.add(k)

    return cluster

def cluster_add_disk(cluster, site, rack, node, disk):
    name = map2name([site, rack, node, disk])
    cluster.add(name)

    return cluster

def cluster_del_disk(cluster, site, rack, node, disk):
    name = map2name([site, rack, node, disk])
    cluster.delete(name)

    return cluster

def disks_of_cluster(cluster):
    #return [[site, rack, node, disk], [site, rack, node, disk], ...]
    rs = []

    for disk_ent in cluster.disk.child:
        rs.append(name2map(disk_ent.id))

    return rs

def disks_of_site(cluster, site):
    #return [[site, rack, node, disk], [site, rack, node, disk], ...]
    rs = []

    for disk_ent in cluster.disk.child:
        lst = name2map(disk_ent.id)
        if lst[0] == site:
            rs.append(lst)

    return rs

def disks_of_rack(cluster, site, rack):
    #return [[site, rack, node, disk], [site, rack, node, disk], ...]
    rs = []

    for disk_ent in cluster.disk.child:
        lst = name2map(disk_ent.id)
        if lst[0] == site and lst[1] == rack:
            rs.append(lst)

    return rs

def disks_of_node(cluster, site, rack, node):
    #return [[site, rack, node, disk], [site, rack, node, disk], ...]
    rs = []

    for disk_ent in cluster.disk.child:
        lst = name2map(disk_ent.id)
        if lst[0] == site and lst[1] == rack and lst[2] == node:
            rs.append(lst)

    return rs

def site_of_disks_max(cluster):
    #return site
    disksnum = -1
    index = 0

    for i in range(len(cluster.site.child)):
        site = cluster.site.child[i].name

        if disksnum < 0:
            disksnum = len(disks_of_site(cluster, site))
            index = i
            continue

        if disksnum < len(disks_of_site(cluster, site)):
            index = i

    return cluster.site.child[index].name

def rack_of_disks_max(cluster, site):
    #return [site, rack]
    disksnum = -1
    index = 0
    racks_ent = []

    for s in cluster.site.child:
        if s.name == site:
            racks_ent = s.child
            break

    for i in range(len(racks_ent)):
        rack = racks_ent[i].name

        if disksnum < 0:
            disksnum = len(disks_of_rack(cluster, site, rack))
            index = i
            continue

        if disksnum < len(disks_of_rack(cluster, site, rack)):
            index = i

    return [site, racks_ent[index].name]

def node_of_disks_max(cluster, site, rack):
    #return [site, rack, node]
    disksnum = -1
    index = 0
    nodes_ent = []

    for s in cluster.site.child:
        if s.name == site:
            for r in s.child:
                if r.name == rack:
                    nodes_ent = r.child
                    break


    for i in range(len(nodes_ent)):
        node = nodes_ent[i].name

        if disksnum < 0:
            disksnum = len(disks_of_node(cluster, site, rack, node))
            index = i
            continue

        if disksnum < len(disks_of_node(cluster, site, rack, node)):
            index = i

    return [site, rack, nodes_ent[index].name]

def get_random_site(cluster):
    #return site
    i = random.randint(0, len(cluster.site.child)-1)
    return cluster.site.child[i].name

def get_random_rack(cluster, site):
    #return [site, rack]
    racks_ent = []

    for s in cluster.site.child:
        if s.name == site:
            racks_ent = s.child
            break

    i = random.randint(0, len(racks_ent)-1)
    return [site, racks_ent[i].name]

def get_random_node(cluster, site, rack):
    #return [site, rack, node]
    nodes_ent = []

    for s in cluster.site.child:
        if s.name == site:
            for r in s.child:
                if r.name == rack:
                    nodes_ent = r.child
                    break

    i = random.randint(0, len(nodes_ent)-1)
    return [site, rack, nodes_ent[i].name]

def get_random_disk(cluster, site, rack, node):
    #return [site, rack, node, disk]
    disks_ent = []

    for s in cluster.site.child:
        if s.name == site:
            for r in s.child:
                if r.name == rack:
                    for h in r.child:
                        if h.name == node:
                            disks_ent = h.child
                            break

    i = random.randint(0, len(disks_ent)-1)
    return [site, rack, node, disks_ent[i].name]

def get_sites_of_gt_one_disk(cluster):
    #return [site, ...]
    rs =  []

    for site_ent in cluster.site.child:
        if len(disks_of_site(cluster, site_ent.name)) > 1:
            rs.append(site_ent.name)

    return rs

def get_racks_of_gt_one_disk(cluster, site):
    #return [[site, rack], [site, rack]]
    rs = []

    racks_ent = []
    for s in cluster.site.child:
        if s.name == site:
            racks_ent = s.child
            break

    for rack_ent in racks_ent:
        if len(disks_of_rack(cluster, site, rack_ent.name)) > 1:
            rs.append([site, rack_ent.name])

    return rs

def get_nodes_of_gt_one_disk(cluster, site, rack):
    #return [[site, rack, node], [site, rack, node]]
    rs = []

    for s in cluster.site.child:
        if s.name == site:
            for rack_ent in s.child:
                if rack_ent.name == rack:
                    for node_ent in rack_ent.child:
                        if len(disks_of_node(cluster, site, rack, node_ent.name)) > 1:
                            rs.append([site, rack, node_ent.name])

    return rs


if __name__ == "__main__":
    pass
